package com.dux.commons.network;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 这个类是调度器实现类，有接受连接、读、写、关闭连接功能。
 * @author 杜祥
 * @create 2013-6-4
 */
public class AcceptReadWriteDispatcherImpl extends Dispatcher
{
	
	/**
	 * 等待关闭连接列表
	 */
	private List<MMOConnection> pendingClose = new ArrayList<MMOConnection>();
	
	/**
	 * 构造一个调度器实例，设置调度器的名称和关闭连接使用的线程池
	 * @param name
	 * 							调度器名称
	 * @param dcPool
	 * 							线程池
	 * @throws IOException
	 */
	public AcceptReadWriteDispatcherImpl(String name, DisconnectionThreadPool dcPool) throws IOException
	{
		super(name, dcPool);
	}

	
	/**
	 * 将指定的连接增加到待关闭列表中，等待调度器关闭
	 */
	@Override
	void closeConnection(MMOConnection connection)
	{
		synchronized (pendingClose) 
		{
			pendingClose.add(connection);
		}
	}

	
	@Override
	void dispatch() throws IOException 
	{
		processPendingClose();
		
		if(this.selector.select() != 0)
		{
			Iterator<SelectionKey> selectedKeys = this.selector.selectedKeys().iterator();
			
			while(selectedKeys.hasNext())
			{
				SelectionKey key = selectedKeys.next();
				selectedKeys.remove();
				
				if(!key.isValid())
					continue;
				
				switch(key.readyOps())
				{
					case SelectionKey.OP_ACCEPT:
						this.accept(key);
						break;
					case SelectionKey.OP_READ:
						this.read(key);
						break;
					case SelectionKey.OP_WRITE:
						this.write(key);
						break;
					case SelectionKey.OP_READ | SelectionKey.OP_WRITE:
						this.read(key);
						if(key.isValid())
							this.write(key);
						break;
				}
			}
		}
	}
	
	
	/**
	 * 这个方法是处理待关闭连接的
	 */
	private void processPendingClose()
	{
		synchronized (pendingClose)
		{
			for(MMOConnection connection : pendingClose)
				closeConnectionImpl(connection);
			
			pendingClose.clear();
		}
	}

}
